﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Entity;
using System.Data;
using System.Linq.Expressions;
using LOMBARDISPICK.Model;

namespace LOMBARDISPICK.Model.Infrastructure
{
	public abstract class RepositoryBase<T> where T : class
	{
		private LombardisPickEntities dataContext;
		private readonly IDbSet<T> dbset;
		protected RepositoryBase(IDatabaseFactory databaseFactory)
		{
			DatabaseFactory = databaseFactory;
			dbset = DataContext.Set<T>();
		}

		protected IDatabaseFactory DatabaseFactory
		{
			get;
			private set;
		}

		protected LombardisPickEntities DataContext
		{
			get { return dataContext ?? (dataContext = DatabaseFactory.Get()); }
		}
		//made a public method to return dataContext to allow for joins on dbsets rather than IENumerables.  Breaks encapsolation so use carefully.
		public virtual LombardisPickEntities getDataContext()
		{
			return DataContext;
		}
		public virtual void add(T entity)
		{
			dbset.Add(entity);
		}
		public virtual void update(T entity)
		{
			dbset.Attach(entity);
			dataContext.Entry(entity).State = EntityState.Modified;
		}
		public virtual void delete(T entity)
		{
			dbset.Remove(entity);
		}
		public virtual void delete(Expression<Func<T, bool>> where)
		{
			IEnumerable<T> objects = dbset.Where<T>(where).AsEnumerable();
			foreach (T obj in objects)
				dbset.Remove(obj);
		}
		public virtual T getById(long id)
		{
			return dbset.Find(id);
		}
		public virtual T getById(string id)
		{
			return dbset.Find(id);
		}
		public virtual IEnumerable<T> getAll()
		{
			return dbset.ToList();
		}
		public virtual IEnumerable<T> getMany(Expression<Func<T, bool>> where)
		{
			return dbset.Where(where).ToList();
		}
		public T get(Expression<Func<T, bool>> where)
		{
			return dbset.Where(where).FirstOrDefault<T>();
		}
	}
}
